﻿using Moq;
using NUnit.Framework;
using System.Collections.Generic;
using System.Threading.Tasks;
using TabbedTemplate.Models;
using TabbedTemplate.Services;
using TabbedTemplate.ViewModels;
using UnitTest.helpers;

namespace UnitTest.ViewModels
{
    public class TestQueryPageViewModel
    {
        [SetUp, TearDown]
        public static void RemoveDatabaseFile() =>
            QueryCacheHelper.RemoveDatabaseFile();

        [Test]
        public async Task TestPerformSearch()
        {
            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;

            var queryPageViewModel = new QueryPageViewModel(null, null,
                mockPunchNavigationService, null, null);

            string query = "蜜雪冰城";
            await queryPageViewModel.PerformSearchCommandFunction(query);
            ClassifySearchParameter classifySearchParameter =
                new ClassifySearchParameter
                {
                    Tag = "",
                    Input = query
                };

            punchNavigationServiceMock.Verify(
                p => p.NavigateToAsync(
                    ContentNavigationConstant.QueryResultPage, It.IsAny<ClassifySearchParameter>()),
                Times.Once);
        }


        [Test]
        public async Task TestPageAppearingCommandQueryTableNotInitialized()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();

            preferenceStorageMock
                .Setup(p => p.Get(QueryServiceConstants.VersionKey, -1))
                .Returns(-1);

            var mockPreferenceStorage = preferenceStorageMock.Object;
            var mockQueryService = new QueryService(mockPreferenceStorage);
            var QueryPageViewModel =
                new QueryPageViewModel(null, null, null, mockQueryService,
                    null);
            await QueryPageViewModel.PageAppearingCommandFunction();
            preferenceStorageMock.Verify(p => p.Get(QueryServiceConstants.VersionKey, -1), Times.Once);
            var res = mockQueryService.Initialized();
            Assert.IsFalse(res);
            await mockQueryService.CloseAsync();
        }

        [Test]
        public async Task TestPageAppearingCommandQueryTableInitialized()
        {
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            preferenceStorageMock
                .Setup(p => p.Get(QueryServiceConstants.VersionKey, -1))
                .Returns(QueryServiceConstants.Version);

            var mockPreferenceStorage = preferenceStorageMock.Object;
            var mockQueryService = new QueryService(mockPreferenceStorage);
            await mockQueryService.InitializeAsync();
            var QueryPageViewModel =
                new QueryPageViewModel(null, null, null, mockQueryService,
                    null);
            await QueryPageViewModel.PageAppearingCommandFunction();
            preferenceStorageMock.Verify(p => p.Get(QueryServiceConstants.VersionKey, -1), Times.Once);
            var res = mockQueryService.Initialized();
            Assert.IsTrue(res);
            await mockQueryService.CloseAsync();
        }

        [Test]
        public async Task TestTappedHotSearch()
        {

            var cityName = "北京市";
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            preferenceStorageMock.Setup(p => p.Get("City", "北京市")).Returns(cityName);
            var mockPreferenceStorage = preferenceStorageMock.Object;

            var res = new SearchItemToReturn
            {
                HasCache = false
            };

            var locationServiceMock = new Mock<ILocationService>();
            locationServiceMock.Setup(p => p.GetCityByPosition(It.IsAny<Position>())).ReturnsAsync(cityName);
            var mockLocationService = locationServiceMock.Object;


            var queryServiceMock = new Mock<IQueryService>();
            queryServiceMock.Setup(p => p.GetSearchItemByString("蜜雪冰城", cityName)).ReturnsAsync(res);
            var mockQueryService = queryServiceMock.Object;


            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;

            var queryPageViewModel = new QueryPageViewModel(null,
                mockPreferenceStorage, mockPunchNavigationService, mockQueryService, mockLocationService);

            await queryPageViewModel.TappedHotSearchFunction("蜜雪冰城");
            queryServiceMock.Verify(p => p.InsertSearchItem(It.IsAny<string>(), cityName), Times.Once);
            preferenceStorageMock.Verify(p => p.Get("City", "北京市"), Times.Once);
            await mockQueryService.CloseAsync();
        }

        [Test]
        public async Task TestTappedHisSearchFunction()
        {
            var cityName = "北京市";
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            preferenceStorageMock.Setup(p => p.Get("City", "北京市")).Returns(cityName);
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var punchNavigationServiceMock =
                new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;

            var queryPageViewModel = new QueryPageViewModel(null,
                mockPreferenceStorage, mockPunchNavigationService, null, null);
            await queryPageViewModel.TappedHisSearchFunction("蜜雪冰城");
            preferenceStorageMock.Verify(p => p.Get("City", "北京市"), Times.Once);
        }

        [Test]
        public async Task TestPageAppearingCommandQueryServiceInitialized()
        {
            var queryServiceMock = new Mock<IQueryService>();
            queryServiceMock.Setup(p => p.Initialized()).Returns(true);

            var list = new List<SearchItemCache> {
                new SearchItemCache {City = "沈阳市", SearchContent = "搜索"},
                new SearchItemCache {City = "沈阳市", SearchContent = "搜索"},
                new SearchItemCache {City = "沈阳市", SearchContent = "搜索"}
            };
            queryServiceMock.Setup(p => p.GetTenItems()).ReturnsAsync(list);
            var mockQueryService = queryServiceMock.Object;

            var queryPageViewModel =
                new QueryPageViewModel(null, null, null, mockQueryService,
                    null);
            await queryPageViewModel.PageAppearingCommandFunction();

            Assert.IsTrue(queryPageViewModel.SearchHistoryList.Count == list.Count);
            queryServiceMock.Verify(p => p.InitializeAsync(), Times.Never);
        }


        [Test]
        public async Task TestPageAppearingCommandQueryServiceNotInitialized()
        {
            var queryServiceMock = new Mock<IQueryService>();
            queryServiceMock.Setup(p => p.Initialized()).Returns(false);

            var list = new List<SearchItemCache> {
                new SearchItemCache {City = "沈阳市", SearchContent = "搜索"},
                new SearchItemCache {City = "沈阳市", SearchContent = "搜索"},
                new SearchItemCache {City = "沈阳市", SearchContent = "搜索"}
            };
            queryServiceMock.Setup(p => p.GetTenItems()).ReturnsAsync(list);
            var mockQueryService = queryServiceMock.Object;

            var queryPageViewModel =
                new QueryPageViewModel(null, null, null, mockQueryService,
                    null);
            await queryPageViewModel.PageAppearingCommandFunction();

            Assert.IsTrue(queryPageViewModel.SearchHistoryList.Count == list.Count);
            queryServiceMock.Verify(p => p.InitializeAsync(), Times.Once);
        }
    }
}
